package template

import (
	"fmt"
	"go-quick/interface/itemplate"
	"regexp"
)

var (
	reIdentifiers    = regexp.MustCompile("^[a-zA-Z0-9_]+$")
	autoScape        = true
	pongoMetaContext = Context{
		"version": itemplate.Version,
	}
)

type Context map[string]any

func (c Context) checkForValidIdentifiers() *Error {
	for k, v := range c {
		if !reIdentifiers.MatchString(k) {
			return &Error{
				Sender:    "checkForValidIdentifiers",
				OrigError: fmt.Errorf("context-key '%s' (value: '%+v') is not a valid identifier", k, v),
			}
		}
	}
	return nil
}

// Update updates this context with the key/value-pairs from another context.
func (c Context) Update(other Context) Context {
	for k, v := range other {
		c[k] = v
	}
	return c
}

type ExecutionContext struct {
	template *Template

	AutoSpace bool
	Public    Context
	Private   Context
	Shared    Context
}

func NewExecutionContext(tpl *Template, ctx Context) *ExecutionContext {
	privateCtx := make(Context)
	privateCtx["pongo"] = pongoMetaContext
	return &ExecutionContext{
		template:  tpl,
		Public:    ctx,
		Private:   privateCtx,
		AutoSpace: autoScape,
	}
}

func NewChildExecutionContext(parent *ExecutionContext) *ExecutionContext {
	newCtx := &ExecutionContext{
		template: parent.template,

		Public:    parent.Public,
		Private:   make(Context),
		AutoSpace: parent.AutoSpace,
	}

	newCtx.Shared = parent.Shared
	newCtx.Private.Update(parent.Private)
	return newCtx
}
